﻿using System;
using System.Collections.Generic;
using System.Linq;
using Algoritmia.Utils;

namespace Algoritmia.Problems.Geometry.Brownian
{
    public class BrownianMotionPointsGenerator
    {
        private readonly IRandomProvider _random;

        public BrownianMotionPointsGenerator(Func<IRandomProvider> createRandomGenerator = null)
        {
            createRandomGenerator = createRandomGenerator ?? (() => new RandomGaussian());
            _random = createRandomGenerator();
        }

        public IEnumerable<Point2D> Points(Point2D a, Point2D b, double r)
        {
            Func<Point2D, Point2D, double,IEnumerable<Point2D>> f = null;
            f = (c, d, v) =>
                    {
                        if ( d.X - c.X <= 1.0 )
                        {
                            return new Point2D[] {};
                        }
                        var delta = _random.NextGaussian(0.0, Math.Sqrt(r));
                        var pt = new Point2D((c.X + d.X)/2.0, (c.Y + d.Y)/2.0 + delta);
                        return f(c, pt, v/2.0).Concat(new[] {pt}).Concat(f(pt, d, v/2.0));
                    };

            return new[] {a}.Concat(f(a, b, r)).Concat(new[] {b});
        }

    }
}
